<template>
	<div class="feature-edit">
		<div class="tools">
			<div
				v-for="item in toolList"
				:key="item.content"
				class="tool"
				:class="{ active: activeTool === item.type }"
				@click="handleEvent(item.type)"
			>
				<i>
					<svg-icon :name="item.iconName" />
				</i>
				<span>{{ item.content }}</span>
			</div>
		</div>
		<div class="exit" @click="emits('exitEdit')">
			<i class="icon"></i>
			<span>退出编辑</span>
		</div>
		<div v-show="isEdit" class="operation">
			<span @click="handleSave">保存</span>
			<span @click="handleCancel(true)">取消</span>
		</div>
		<el-dialog
			v-model="dialogVisible"
			title="矢量类型"
			width="300px"
			append-to-body
			:before-close="handleClose"
		>
			<el-form-item label="矢量类型" prop="userName">
				<el-select v-model="shpType" placeholder="请选择新增的矢量类型">
					<el-option
						v-for="item in interpretValList"
						:key="item"
						:label="interpretTypeList[item].label"
						:value="item"
					/>
				</el-select>
			</el-form-item>
			<template #footer>
				<span class="dialog-footer">
					<el-button type="primary" @click="handleAdd">确定</el-button>
					<el-button @click="handleClose">取消</el-button>
				</span>
			</template>
		</el-dialog>
	</div>
</template>

<script lang="ts" setup>
import { ElMessage, ElMessageBox } from "element-plus";
import { ref, onActivated, onDeactivated } from "vue";
import mapTool from "@/utils/maptools/map";
import geoUtil from "@/utils/turf/geoUtil.js";
import { updateShp, addShp, delShp } from "@/api/ai-processing";
import type { taskListItem } from "@/api/ai-processing/types";
import { useTaskStore } from "@/store";
const props = defineProps<{
	mIndex: string;
	curItem: taskListItem | undefined;
}>();

const emits = defineEmits(["watchShp", "exitEdit"]);

// 激活的工具
const activeTool = ref("");
// 是否正在编辑
const isEdit = ref(false);
// 选中要素
const selectedFeature = ref();
// 已修改要素列表
const modifyFeatureList: Ref<any[]> = ref([]);
// 已绘制的要素
const drawnFeature = ref();
/**-------------------弹窗相关--------------------------------*/
const interpretTypeList = BASE_CONFIG.vectorColor;
const interpretValList = Object.keys(interpretTypeList);
// 弹框显隐
const dialogVisible = ref(false);
// 矢量类型
const shpType = ref("farmland");
const taskStore = useTaskStore();

// 弹框确认事件
const handleAdd = () => {
	// taskStore.setInfo({
	// 	currentInterpretType: taskStore.currentInterpretType + "," + shpType.value,
	// });
	dialogVisible.value = false;
};
// 弹框取消事件
const handleClose = () => {
	dialogVisible.value = false;
	handleCancel(false);
};
/**-------------------弹窗相关--------------------------------*/
// 地图工具列表
const toolList = [
	{
		type: "update",
		iconName: "feature_edit_update",
		content: "修改",
	},
	{
		type: "remining",
		iconName: "feature_edit_remining",
		content: "重采",
	},
	{
		type: "disassemble",
		iconName: "feature_edit_disassemble",
		content: "拆分",
	},
	{
		type: "merge",
		iconName: "feature_edit_merge",
		content: "合并",
	},
	{
		type: "add",
		iconName: "feature_edit_add",
		content: "新增",
	},
	{
		type: "delete",
		iconName: "measure_clear",
		content: "删除",
	},
];
// 工具栏点击处理
const handleEvent = (type: string) => {
	// 确保选中要素后进行操作
	if (
		(!selectedFeature.value && type !== "add") ||
		(selectedFeature.value?.length === 0 && type !== "add")
	) {
		ElMessage.warning("请选中要素后再进行当前操作！");
		return;
	}
	// 避免操作冲突
	if (activeTool.value !== "") {
		ElMessage.warning("请先保存或取消当前操作后再进行其他操作！");
		return;
	}
	if (type === "delete") {
		ElMessageBox.confirm("确认删除当前选中的矢量?", "提示", {
			confirmButtonText: "确认",
			cancelButtonText: "取消",
		})
			.then(() => {
				// 确认
				activeTool.value = type;
				handleSave();
			})
			.catch(() => {
				// 取消
			});
		return;
	}
	activeTool.value = type;
	isEdit.value = true;
	switch (type) {
		// 修改
		case "update": {
			mapTool.addModifyInteraction(
				props.mIndex,
				[
					// {
					// 	eventType: "modifystart",
					// 	event: function (evt: any) {
					// 		const feature = evt.features.getArray()[0];
					// 		// mapTool.changeFeatureStatus(feature);
					// 	},
					// },
					{
						eventType: "modifyend",
						event: function (evt: any) {
							const feature = evt.features.getArray()[0];
							const idAndInterpretType = feature.getId();
							const id = idAndInterpretType.split("_")[0];
							const index = modifyFeatureList.value.findIndex((item) => item.id === id);
							if (index === -1) {
								modifyFeatureList.value.push({ id, feature });
							} else {
								modifyFeatureList.value.splice(index, 1, { id, feature });
							}
						},
					},
				],
				selectedFeature.value
			);
			break;
		}
		// 拆分
		case "disassemble": {
			mapTool.addDrawInteraction(props.mIndex, "LineString", [
				{
					eventType: "drawstart",
					event: function () {
						if (drawnFeature.value) {
							mapTool.vectorLayerList[props.mIndex]?.getSource()?.removeFeature(drawnFeature.value);
						}
					},
				},
				{
					eventType: "drawend",
					event: function (evt: any) {
						drawnFeature.value = evt.feature;
					},
				},
			]);
			break;
		}
		// 合并
		case "merge": {
			mapTool.addDrawInteraction(props.mIndex, "Polygon", [
				{
					eventType: "drawstart",
					event: function () {
						if (drawnFeature.value) {
							mapTool.vectorLayerList[props.mIndex]?.getSource()?.removeFeature(drawnFeature.value);
						}
					},
				},
				{
					eventType: "drawend",
					event: function (evt: any) {
						drawnFeature.value = evt.feature;
					},
				},
			]);
			break;
		}
		// 新增和重采
		case "remining":
		case "add": {
			if (type === "add") {
				dialogVisible.value = true;
			}
			mapTool.addDrawInteraction(props.mIndex, "Polygon", [
				{
					eventType: "drawstart",
					event: function () {
						if (drawnFeature.value) {
							mapTool.vectorLayerList[props.mIndex]?.getSource()?.removeFeature(drawnFeature.value);
							drawnFeature.value = undefined;
						}
					},
				},
				{
					eventType: "drawend",
					event: function (evt: any) {
						drawnFeature.value = evt.feature;
					},
				},
			]);
			break;
		}
		// 删除
		case "delete": {
			break;
		}
	}
};

// 保存
const handleSave = async () => {
	// 定位编辑的矢量
	let locationGeo: string;
	// 重新加载时间
	let timeout = BASE_CONFIG.delayTime ? BASE_CONFIG.delayTime : 20;
	if (props.curItem?.taskId === undefined) {
		return;
	}
	switch (activeTool.value) {
		case "update": {
			for (let i = 0; i < modifyFeatureList.value.length; i++) {
				const item = modifyFeatureList.value[i];
				const geo = mapTool.featureToWkt(item.feature);
				await updateShp({ id: item.id, geo });
				locationGeo = geo;
			}
			break;
		}
		case "disassemble": {
			const idAndInterpretType = selectedFeature.value[0].getId();
			const interpretType = idAndInterpretType.split("_")[1];
			const id = idAndInterpretType.split("_")[0];
			const feature = selectedFeature.value[0];
			const clipFeature = drawnFeature.value;
			const polygon = mapTool.featureToGeoJson(feature);
			const clipLine = mapTool.featureToGeoJson(clipFeature);
			const result = geoUtil.polygonClipByLine(polygon, clipLine);
			// 删除原来的矢量
			await delShp(id);
			// 新增矢量
			for (let i = 0; i < result.features.length; i++) {
				const feature: any = mapTool.geoJsonToFeature(result.features[i]);
				const geo = mapTool.featureToWkt(feature);
				await addShp({
					taskId: props.curItem.taskId,
					geo,
					interpretType,
				});
				locationGeo = geo;
			}
			break;
		}
		case "merge": {
			const idAndInterpretType = selectedFeature.value[0].getId();
			const interpretType = idAndInterpretType.split("_")[1];
			const id = idAndInterpretType.split("_")[0];
			const feature = selectedFeature.value[0];
			const mergeFeature = drawnFeature.value;
			const polygon1 = mapTool.featureToGeoJson(feature);
			const polygon2 = mapTool.featureToGeoJson(mergeFeature);
			const result = geoUtil.unionPolygon([polygon1, polygon2]);
			const newFeature: any = mapTool.geoJsonToFeature(result);
			const geo = mapTool.featureToWkt(newFeature);
			// 删除原来的矢量
			await delShp(id);
			// 新增矢量
			await addShp({
				taskId: props.curItem.taskId,
				geo,
				interpretType,
			});
			locationGeo = geo;
			break;
		}
		case "remining":
		case "add": {
			const geo = mapTool.featureToWkt(drawnFeature.value);
			if (activeTool.value === "remining") {
				const idAndInterpretType = selectedFeature.value[0].getId();
				const id = idAndInterpretType.split("_")[0];
				await updateShp({
					id,
					geo,
				});
			} else {
				await addShp({
					taskId: props.curItem.taskId,
					geo,
					interpretType: shpType.value,
				});
			}
			locationGeo = geo;
			break;
		}
		case "delete": {
			const idAndInterpretType = selectedFeature.value[0].getId();
			const id = idAndInterpretType.split("_")[0];
			await delShp(id);
			locationGeo = "delete";
			timeout += 60;
			break;
		}
	}
	// 消除后台反应慢的问题
	setTimeout(() => {
		handleCancel(true, locationGeo);
	}, timeout);
};
// 取消
const handleCancel = (flag: boolean, locationGeo = "") => {
	switch (activeTool.value) {
		case "update": {
			mapTool.removeModifyInteraction(props.mIndex);
			modifyFeatureList.value = [];
			break;
		}
		case "disassemble": {
			mapTool.removeDrawInteraction(props.mIndex);
			break;
		}
		case "merge": {
			mapTool.removeDrawInteraction(props.mIndex);
			break;
		}
		case "remining":
		case "add": {
			drawnFeature.value = undefined;
			mapTool.removeDrawInteraction(props.mIndex);
			break;
		}
		case "delete": {
			break;
		}
	}
	if (flag) {
		// 重载矢量
		emits("watchShp", props.curItem, true, locationGeo);
	}
	selectedFeature.value = undefined;
	activeTool.value = "";
	isEdit.value = false;
};

onActivated(() => {
	if (props.curItem) {
		// 添加选中事件
		mapTool.addSelectInteraction(props.mIndex, [
			{
				eventType: "select",
				event: function (evt: any) {
					if (!isEdit.value) {
						selectedFeature.value = evt.selected;
					}
				},
			},
		]);
	}
});

onDeactivated(() => {
	handleCancel(false);
	mapTool.removeSelectInteraction(props.mIndex);
});
</script>

<style lang="scss" scoped>
.feature-edit {
	position: relative;
	padding: 3px 0 8px;
	display: flex;
	flex-direction: column;
	align-items: center;
	box-sizing: border-box;
	border-radius: 6px;
	border: 1px solid #3989c2;
	// background: rgba(6, 19, 44, 0.8);

	background: rgba(13, 19, 30, 0.8);
	box-shadow: 0px 4px 4px 0px rgba(0, 0, 0, 0.25);
	&::before {
		content: "";
		width: 390px;
		height: 7px;

		background: linear-gradient(
			180deg,
			rgba(42, 122, 207, 0.6391) 0%,
			rgba(1, 12, 18, 0.5698) 100%
		);
		border-radius: 8px;
	}
	.tools {
		margin-top: -2px;
		display: flex;
		padding: 0 8px;
		.tool {
			margin-right: 4px;
			width: 60px;
			height: 60px;
			display: flex;
			flex-direction: column;
			justify-content: center;
			align-items: center;
			font-size: 14px;
			color: rgba(193, 242, 255, 0.6);
			border-radius: 4px;
			cursor: pointer;
			&:last-child {
				margin-right: 0;
			}
			&.active {
				background: linear-gradient(
					180deg,
					rgba(35, 136, 244, 0.6) 0%,
					rgba(0, 123, 255, 0.6) 100%
				);
				color: #fff;
			}
			&:hover {
				color: #c1f2ff;
			}
			i {
				font-size: 20px;
			}
			span {
				margin-top: 4px;
				display: inline-block;
				width: 30px;
				text-align: center;
			}
		}
	}
	.exit {
		position: absolute;
		right: -96px;
		top: -1px;
		width: 77px;
		height: 78px;
		display: flex;
		flex-direction: column;
		align-items: center;
		justify-content: center;
		background: url("../../assets/images/feature-edit/exit_bg_nor.png") center center no-repeat;
		background-size: 100% 100%;
		cursor: pointer;
		&:hover {
			background: url("../../assets/images/feature-edit/exit_bg_act.png") center center no-repeat;
			background-size: 100% 100%;
			.icon {
				background: url("../../assets/images/feature-edit/exit_act.png") center center no-repeat;
				background-size: 100% 100%;
			}
			span {
				color: #fff;
			}
		}
		.icon {
			width: 20px;
			height: 20px;
			background: url("../../assets/images/feature-edit/exit_nor.png") center center no-repeat;
			background-size: 100% 100%;
		}
		span {
			padding-top: 5px;
			font-size: 14px;
			line-height: 20px;
			color: rgba(193, 242, 255, 0.6);
		}
	}
	.operation {
		position: absolute;
		left: calc(50% + 48px);
		bottom: -14px;
		display: flex;
		align-items: center;
		justify-content: center;
		width: 182px;
		height: 38px;
		box-sizing: border-box;
		transform: translate(-50%, 100%);
		color: #fff;
		border-radius: 20px;
		border: 1px solid #3989c2;
		background: rgba(13, 19, 30, 0.8);
		span {
			width: 89px;
			font-size: 15px;
			line-height: 24px;
			text-align: center;
			cursor: pointer;
			&:first-child {
				position: relative;
				left: 4.5px;
				background: url("../../assets/images/feature-edit/save_nor.png") center center no-repeat;
				background-size: 100% 100%;
				&:hover {
					background: url("../../assets/images/feature-edit/save_act.png") center center no-repeat;
				}
				&:active {
					opacity: 0.8;
					background: url("../../assets/images/feature-edit/save_act.png") center center no-repeat;
				}
			}
			&:last-child {
				position: relative;
				left: -4.5px;
				background: url("../../assets/images/feature-edit/cancel_nor.png") center center no-repeat;
				&:hover {
					background: url("../../assets/images/feature-edit/cancel_act.png") center center no-repeat;
				}
				&:active {
					opacity: 0.8;
					background: url("../../assets/images/feature-edit/cancel_act.png") center center no-repeat;
				}
			}
		}
	}
}
</style>
